<template>
  <div class="axiom-select" :class="{ 'axiom-select--block': block }">
    <label v-if="label" :for="selectId" class="axiom-select__label">
      {{ label }}
      <span v-if="required" class="axiom-select__required">*</span>
    </label>
    <div :class="['axiom-select__field', { 'axiom-select__field--error': error }]">
      <el-select
        v-bind="$attrs"
        :id="selectId"
        :model-value="modelValue"
        @update:modelValue="$emit('update:modelValue', $event)"
        @change="$emit('change', $event)"
        @visible-change="$emit('visible-change', $event)"
        @remove-tag="$emit('remove-tag', $event)"
        @clear="$emit('clear')"
        @blur="$emit('blur', $event)"
        @focus="$emit('focus', $event)"
        :placeholder="placeholder"
        :disabled="disabled"
        :clearable="clearable"
        :filterable="filterable"
        :multiple="multiple"
        :multiple-limit="multipleLimit"
        :collapse-tags="collapseTags"
        :collapse-tags-tooltip="collapseTagsTooltip"
        :allow-create="allowCreate"
        :filter-method="filterMethod"
        :remote="remote"
        :remote-method="remoteMethod"
        :loading="loading"
        :loading-text="loadingText"
        :no-match-text="noMatchText"
        :no-data-text="noDataText"
        :popper-class="popperClass"
        :reserve-keyword="reserveKeyword"
        :default-first-option="defaultFirstOption"
        :teleported="teleported"
        :automatic-dropdown="automaticDropdown"
        :size="size"
      >
        <slot>
          <el-option
            v-for="option in options"
            :key="option[valueKey]"
            :label="option[labelKey]"
            :value="option[valueKey]"
            :disabled="option.disabled"
          >
            <slot name="option" :option="option">{{ option[labelKey] }}</slot>
          </el-option>
        </slot>
        <template v-if="$slots.prefix" #prefix>
          <slot name="prefix" />
        </template>
        <template v-if="$slots.empty" #empty>
          <slot name="empty" />
        </template>
      </el-select>
    </div>
    <div v-if="error" class="axiom-select__error">{{ error }}</div>
    <div v-if="helpText && !error" class="axiom-select__help">{{ helpText }}</div>
  </div>
</template>

<script setup>
import { computed } from 'vue';

defineOptions({
  name: 'AxiomSelect'
});

const props = defineProps({
  label: { type: String, default: '' },
  required: { type: Boolean, default: false },
  placeholder: { type: String, default: '请选择' },
  disabled: { type: Boolean, default: false },
  clearable: { type: Boolean, default: true },
  filterable: { type: Boolean, default: false },
  multiple: { type: Boolean, default: false },
  multipleLimit: { type: Number, default: 0 },
  collapseTags: { type: Boolean, default: false },
  collapseTagsTooltip: { type: Boolean, default: false },
  allowCreate: { type: Boolean, default: false },
  filterMethod: { type: Function, default: null },
  remote: { type: Boolean, default: false },
  remoteMethod: { type: Function, default: null },
  loading: { type: Boolean, default: false },
  loadingText: { type: String, default: '加载中' },
  noMatchText: { type: String, default: '无匹配数据' },
  noDataText: { type: String, default: '无数据' },
  popperClass: { type: String, default: '' },
  reserveKeyword: { type: Boolean, default: true },
  defaultFirstOption: { type: Boolean, default: false },
  teleported: { type: Boolean, default: true },
  automaticDropdown: { type: Boolean, default: false },
  options: { type: Array, default: () => [] },
  valueKey: { type: String, default: 'value' },
  labelKey: { type: String, default: 'label' },
  size: { type: String, default: 'default', validator: (value) => ['large', 'default', 'small'].includes(value) },
  error: { type: String, default: '' },
  helpText: { type: String, default: '' },
  modelValue: { type: [String, Number, Array], default: '' },
  block: { type: Boolean, default: false },
});

defineEmits(['update:modelValue', 'change', 'blur', 'focus', 'clear', 'visible-change', 'remove-tag']);

const selectId = computed(() => `axiom-select-${Math.random().toString(36).substr(2, 9)}`);
</script>

<style lang="scss">
@use '../../styles/components/common/axiom-select';
</style>